/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package kuti.grp5.ui;

import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.KeyStroke;
import kuti.EWorldElementType;
import kuti.IKuti;
import kuti.ISimulParams;
import kuti.IWorldManager;
import kuti.grp5.Kuti;
import kuti.ui.ESimulationPanelMouseMode;
import kuti.ui.ISimulationPanelOperations;
import kuti.ui.LogPanel;

/**
 *
 * @author Jocelyn
 */
public class SimulationPanelOperations implements ISimulationPanelOperations {

    private LogPanel logs;
    private IWorldManager wm;
    private ISimulParams isp;
    private SimulationPanel simP;
    private ESimulationPanelMouseMode mouseMode = ESimulationPanelMouseMode.INFO;
    
    private boolean areTooltipsDisplayed = true;
    private boolean drawRadarBeams;
    private boolean mute = false;
    private boolean isGraphicOverlayed = false;
    private boolean simIsFinished = false;
    
    public SimulationPanelOperations(SimulationPanel simP, IWorldManager wm, LogPanel logs, ISimulParams isp) {
        this.wm = wm;
        this.simP = simP;
        this.logs = logs;
        this.isp = isp;
    }

    public void setSimIsFinished(boolean simIsFinished){
        this.simIsFinished = simIsFinished;
    }
    
    public void setMouseMode(ESimulationPanelMouseMode mouseMode) {
        this.mouseMode = mouseMode;
    }

    @Override
    public ESimulationPanelMouseMode mouseMode() {
        return mouseMode;
    }

    @Override
    public void infoRequest(int atX, int atY) {
        // not used
    }

    @Override
    public void actionRequest(int atX, int atY) {
        // not used
    }

    @Override
    public void zoneSelected(int fromX, int fromY, int toX, int toY) {
        logEntry("Zoom displayed from [" + fromX + "," + fromY + "] to [" + toX + "," + toY + "]");
    }

    public void displayToolTips(boolean areTooltipsDisplayed) {
        this.areTooltipsDisplayed = areTooltipsDisplayed;
    }

    @Override
    public boolean areToolTipsDisplayed() {
        return areTooltipsDisplayed;
    }

    @Override
    public String toolTipText(int atX, int atY, ESimulationPanelMouseMode mouseMode) {
        String txt = "";

        List<IKuti> elts = new ArrayList<IKuti>();
        elts.addAll(wm.getAllKuti());

        IKuti ik = getWorldElementFromCoord(atX, atY, elts);
        if (ik != null) {
            txt = "ID : " + ik.getId();
            txt += " | Energy : " + (int)ik.getEnergyLevel();
            txt += " | Orientation : " + (int)Math.toDegrees(ik.getOrientation()) + "°";
            txt += " | Speed : " + (int)ik.getSpeed();
        } else {
            int[][] lawn = wm.getLawn().getBladeHeight().getBladeHeight();
            if(atY >= lawn.length || atX >= lawn[0].length) return "Deep void";
            txt = "Height : " + lawn[ISimulParams.WORLD_HEIGHT - atY][atX];
        }

        return txt;
    }

    private IKuti getWorldElementFromCoord(int atX, int atY, List<IKuti> elts) {
        for (IKuti iKuti : elts) {
            if (iKuti.getCenterPosition().distance(atX, ISimulParams.WORLD_HEIGHT - atY) < isp.getKDiameter() / 2) {
                return iKuti;
            }
        }
        return null;
    }

    @Override
    public boolean drawRadarBeams() {
        return drawRadarBeams;
    }

    public void setdrawRadarBeams(boolean drawRadarBeams) {
        this.drawRadarBeams = drawRadarBeams;
    }

    @Override
    public boolean isSoundUsed() {
        return true;
    }

    public void setMute(boolean mute){
        this.mute = mute;
    }
    
    @Override
    public boolean mute() {
        return mute;
    }

    @Override
    public boolean isGraphicOverlayed() {
        return isGraphicOverlayed;
    }
    
    public void setGraphicOverlayed(boolean isGraphicOverlayed){
        this.isGraphicOverlayed = isGraphicOverlayed;
    }

    @Override
    public void overlayGraphics(Graphics2D g) {
        // NOTHING TO DO AT THE MOMENT
    }

    
    static abstract class ActionAdapter extends AbstractAction{}
    
    @Override
    public Map<KeyStroke, Action> keyStrokeActionMap(ESimulationPanelMouseMode mouseMode) {
        HashMap<KeyStroke, Action> map = new HashMap<KeyStroke, Action>();
        
        // If the simulation is finished we dont want the user to do actions via shortcuts
        // So this method is force-called again via the simulation panel
        // to give the UISimulationPanel an empty shortcut map.
        if(simIsFinished) return map;
        
        map.put(KeyStroke.getKeyStroke(KeyEvent.VK_Z, 0), new ActionAdapter() {

            @Override
            public void actionPerformed(ActionEvent ae) {
                simP.btZoomAction(false);
            }
        });
        
        map.put(KeyStroke.getKeyStroke(KeyEvent.VK_M, 0), new ActionAdapter() {

            @Override
            public void actionPerformed(ActionEvent ae) {
                simP.btMuteAction(false);
            }
        });
        
        map.put(KeyStroke.getKeyStroke(KeyEvent.VK_T, 0), new ActionAdapter() {

            @Override
            public void actionPerformed(ActionEvent ae) {
                simP.cbToolTipAction(false);
            }
        });
        
        map.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), new ActionAdapter() {

            @Override
            public void actionPerformed(ActionEvent ae) {
                simP.btPlayAction(false);
            }
        });
        
        map.put(KeyStroke.getKeyStroke(KeyEvent.VK_N, 0), new ActionAdapter() {

            @Override
            public void actionPerformed(ActionEvent ae) {
                simP.btDoStepAction(false);
            }
        });
        
        map.put(KeyStroke.getKeyStroke(KeyEvent.VK_K, InputEvent.SHIFT_DOWN_MASK), new ActionAdapter() {

            @Override
            public void actionPerformed(ActionEvent ae) {
                simP.setCurrentCustomElt(EWorldElementType.KUTI);
            }
        });
        
        map.put(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.SHIFT_DOWN_MASK), new ActionAdapter() {

            @Override
            public void actionPerformed(ActionEvent ae) {
                simP.setCurrentCustomElt(EWorldElementType.CHARGING_STATION);
            }
        });
        
        map.put(KeyStroke.getKeyStroke(KeyEvent.VK_M, InputEvent.SHIFT_DOWN_MASK), new ActionAdapter() {

            @Override
            public void actionPerformed(ActionEvent ae) {
                simP.setCurrentCustomElt(EWorldElementType.MAGNETIC_OBSTACLE);
            }
        });
        
        map.put(KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.SHIFT_DOWN_MASK), new ActionAdapter() {

            @Override
            public void actionPerformed(ActionEvent ae) {
                simP.setCurrentCustomElt(EWorldElementType.OBSTACLE);
            }
        });
        return map;
    }

    @Override
    public void logEntry(String logText) {
        logs.addEntry(logText);
    }
}
